iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
0
Mobile Development

用 Flutter 開發一個 Android App 吧系列 第 17

用 Flutter 開發一個 Android App 吧 - Day 17. 搜尋頁面(改)、自製 GitHub Tiles

  • 分享至 

  • xImage
  •  

本系列同步發表在 個人部落格,歡迎大家關注~

搜尋頁面 - 改

github 這套件的加持下,搜尋頁面調用搜尋 API 也變得非常簡單。

在搜尋頁面上我做了以下的調整:

  1. 如同前兩天的作法一樣,搭配 FutureBuilder 來達成異步任務(也就是調用 API)。
  @override
  Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder(
        future: searchResultList,
        builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.done:
              if (!snapshot.hasError) {
                return ListView.separated(...);
              } else {
                return Center(child: Text("No Data"));
              }
              break;
            case ConnectionState.none:
            case ConnectionState.active:
            case ConnectionState.waiting:
              return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
  1. 根據選擇的搜尋類別,調用對應的函數,SearchTypes.repos 調用 githubClient.search.repositoriesSearchTypes.users 調用 githubClient.search.users
// Search Repos
Future<List<Repository>> searchRepos(String searchQuery) async {
  return githubClient.search.repositories(searchQuery).toList();
}

// Search Users
Future<List<User>> searchUsers(String searchQuery) async {
  return githubClient.search.users(searchQuery).toList();
}
  1. 自製 RepoTileUserTile

lib/components/github_tiles.dart

import "package:flutter/material.dart";

class RepoTile extends StatelessWidget {
  const RepoTile({
    Key key,
    @required this.name,
    this.description,
    @required this.stars,
    this.language,
  }) : super(key: key);

  final String name;
  final String description;
  final int stars;
  final String language;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(name),
      subtitle: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SizedBox(height: 8.0),
          description != null
              ? Text(description)
              : Text("No description provided."),
          SizedBox(height: 8.0),
          Text("★ $stars "),
        ],
      ),
      trailing: language != null ? Text(language) : SizedBox(),
      contentPadding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
      onTap: () {},
    );
  }
}

class UserTile extends StatelessWidget {
  const UserTile({
    Key key,
    this.avatarUrl,
    @required this.name,
  }) : super(key: key);

  final String avatarUrl;
  final String name;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: CircleAvatar(
        backgroundImage: NetworkImage(avatarUrl),
        radius: 16.0,
      ),
      title: Text(name),
      dense: true,
      onTap: () {},
    );
  }
}

小提醒:

  • 這裡我額外拉出兩個 Widget RepoTileUserList 寫在 github_tile.dart,原因是發現其實還滿多地方會用到他們的,所以就統一寫在一起,方便管理囉~
  • 有哪些地方還會用到他們? 後續會慢慢看到~

增加 Scrollbar、RefreshIndicator 與 顯示搜尋結果

增加 ScrollbarRefreshIndicator,想必大家不陌生,在本系列 Day 7 時有作講解。

沒印象的可以點 ==> Day7 時光機

顯示搜尋結果上面,預設的函數會顯示 2 pages 60 筆(1 page 為 30 筆資料)。
而通常搜尋到的結果都會出現在前 10 ~ 20 筆(除非你真的找的太冷門...),為了增加搜尋速度,所以把 pages 參數調整為 1。

這裡直接貼上 Commit 的 Diff 圖片給大家參考囉~

day17-1.jpeg

--

修改後成果

day17-2.gif

自製 GitHub Tiles

將前天的倉庫頁,ListTile 的部份替換成剛寫好的 RepoTile
而昨天的議題頁,也是將 ListTile 的部份替換成 IssueTile

class IssueTile extends StatelessWidget {
  const IssueTile({
    Key key,
    @required this.userAvatarUrl,
    @required this.title,
    @required this.createTime,
  }) : super(key: key);

  final String userAvatarUrl;
  final String title;
  final DateTime createTime;

  @override
  Widget build(BuildContext context) {
    final now = DateTime.now();
    final difference = now.difference(createTime);
    final createTimeAgo = timeago.format(now.subtract(difference));

    return ListTile(
      dense: true,
      leading: CircleAvatar(
        radius: 18.0,
        backgroundImage: NetworkImage(userAvatarUrl),
      ),
      title: Text(title),
      subtitle: Text(createTimeAgo),
      trailing: Icon(Icons.error_outline),
      onTap: () {},
    );
  }
}

上一篇
用 Flutter 開發一個 Android App 吧 - Day 16. 題外話、活動頁(改)及議題頁(改)
下一篇
用 Flutter 開發一個 Android App 吧 - Day 18. 個人頁面(大改)
系列文
用 Flutter 開發一個 Android App 吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
Robby
iT邦新手 5 級 ‧ 2020-01-25 14:58:09

感謝分享

我要留言

立即登入留言